home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
simula
/
books
/
books.lha
/
kirkerud
/
stud1.sim
< prev
next >
Wrap
Text File
|
1993-08-16
|
18KB
|
466 lines
% ****************************************************************
% * *
% * This is tre program constructed in chapter 8 of *
% * Object Oriented Programming with Simula by Bj|rn Kirkerud; *
% * *
% ****************************************************************
begin
% ****************************************************************
% * *
% * First a declaration of the pattern for Student-objects: *
% * *
% ****************************************************************
class Student;
begin
integer ident, year, month, day, form;
Boolean female;
character math_grade, eng_grade, hist_grade;
procedure read;
begin
ident := prompt_for_int("Identity number? ");
year := prompt_for_int("Year of birth? ");
month := prompt_for_int("Month? ");
day := prompt_for_int("Day? ");
form := prompt_for_int("Form? ");
female := prompt_for_bool("Female? ");
math_grade := prompt_for_char("Grade in mathematics? ");
eng_grade := prompt_for_char("Grade in English? ");
hist_grade := prompt_for_char("Grade in history? ");
end of Student'read;
procedure write;
begin
outtext("Data for student: "); outint(ident, 6);
outtext(". Born: "); outint(day, 2); outchar('/');
outint(month, 2); outchar('/');
outint(year, 4);
outtext(if female then ". Female." else ". Male."); outimage;
outtext(" Form: "); outint(form, 1);
outtext(". Current grades:");
outtext(" Mathematics: "); outchar(math_grade);
outtext(" English: "); outchar(eng_grade);
outtext(" History: "); outchar(hist_grade); outimage;
end of Student'write;
procedure change;
begin character attribute;
attribute := prompt_for_char("What do you want to change? ");
if attribute = 'i' then ident :=
prompt_for_int("New identity number? ") else
if attribute = 'y' then year :=
prompt_for_int("New birth year? ") else
if attribute = 'm' then month :=
prompt_for_int("New birth month? ") else
if attribute = 'd' then day :=
prompt_for_int("New day of birth? ") else
if attribute = 'f' then form :=
prompt_for_int("New form number? ") else
if attribute = 's' then female :=
prompt_for_bool("Female? ") else
if attribute = 'a' then math_grade :=
prompt_for_char("New grade in math? ") else
if attribute = 'e' then eng_grade :=
prompt_for_char("New grade in English? ") else
if attribute = 'h' then hist_grade :=
prompt_for_char("New grade in history? ")
else begin
User_message("You can change the following attributes:");
User_message(" i: Identity number");
User_message(" y: Birth year");
User_message(" m: Birth month");
User_message(" d: Day of birth");
User_message(" f: Form number");
User_message(" s: Sex");
User_message(" a: Grade in mathematics");
User_message(" e: Grade in English");
User_message(" h: Grade in history");
change; ! Observe that this is an invocation of the procedure
! that is under declaration. The effect of this is
! that this procedure is executed once more, and hence
! that the user is given another chance to change;
end;
end of Student'change;
character procedure worst_grade;
worst_grade := max(math_grade, max(eng_grade, hist_grade));
Boolean procedure is_elder_than(a_student); ref(Student) a_student;
is_elder_than :=
(year < a_student.year) or else
(year = a_student.year and month < a_student.month) or else
(year = a_student.year and month = a_student.month
and day < a_student.day);
procedure put_in_record;
not_implemented("Put in record");
procedure get_from_record;
not_implemented("Get from record");
end of Student;
% ******************************************************************
% * *
% * A class containing declarations of the variables of the data *
% * structure and procedures for accessing the data structure: *
% * *
% ******************************************************************
class School(max_number_of_students); integer max_number_of_students;
protected The_students, number_of_students,
last_index, find_index_of_student;
! The effect of this is to protect these four attributes,
! thus making them inaccessible outside the the class.
! This means that all access of the data structure must
! be via the five data access procedures declared in the class;
begin
! Declaration of data structure which consists of:
! 1: An array which may store references to as many as
! max_number_of_students Students
! 2: An integer which says how many Students are stored in the array: ;
ref(Student) array The_students(1 : max_number_of_students);
integer number_of_students;
! Data invariants: ;
! 1: 0 le number_of_students le max_number_of_students;
! 2: For every stud_n = 1, 2, ... number_of_students:
! The_students(stud_n) points to a Student object, not none;
! 3: For every stud_n = number_of_students + 1, ...,
! max_number_of_students: The_students(stud_n) == none;
! 4: For every s1, s2 = 1, 2, ... number_of_students (s1 ne s2):
! The_students(s1) =/= The_students(s2);
! The_students(s1)ident ne The_students(s2)ident;
! Declaration of an auxiliary integer variable to hold
! the index last used by the procedure next_student: ;
integer last_index;
! Declarations of data access procedures: ;
procedure Place_student(a_student, no_room, ident_exists);
name no_room, ident_exists;
ref(Student) a_student; Boolean no_room, ident_exists;
if number_of_students = max_number_of_students
then no_room := true
else begin
no_room := false;
if find_student(a_student.ident) =/= none then ident_exists := true
else begin
ident_exists := false;
number_of_students := number_of_students + 1;
The_students(number_of_students) :- a_student;
end;
end Place_student;
ref(Student) procedure first_student;
begin
first_student :- The_students(1);
last_index := 1;
end of first_student;
ref(Student) procedure next_student;
begin
last_index := last_index + 1;
next_student :- if last_index > number_of_students
then none
else The_students(last_index);
end of next_student;
procedure Remove_specified_student(ident, no_such_student);
name no_such_student;
integer ident; Boolean no_such_student;
begin integer ident_index; Boolean ident_exists;
find_index_of_student(ident, ident_exists, ident_index);
if ident_exists then
begin
no_such_student := false;
The_students(ident_index) :- The_students(number_of_students);
The_students(number_of_students) :- none;
number_of_students := number_of_students - 1;
end
else no_such_student := true;
end of Remove_specified_student;
ref(Student) procedure find_student(ident_number); integer ident_number;
begin integer student_number; Boolean student_found;
find_index_of_student(ident_number, student_found, student_number);
find_student :- if student_found then The_students(student_number)
else none
end of find_student;
! Declaration of an auxiliary, protected data access procedure: ;
procedure find_index_of_student(ident, ident_found, ident_index);
name ident_found, ident_index;
integer ident, ident_index; Boolean ident_found;
begin
ident_index := 1; ident_found := false;
while ident_index le number_of_students and not ident_found do
if The_students(ident_index).ident = ident
then ident_found := true else ident_index := ident_index + 1;
end of find_index_of_student;
end of School;
% ******************************************
% * *
% * Declarations of command procedures: *
% * *
% ******************************************
procedure Enter_student;
begin ref(Student) a_student; Boolean no_room, ident_exists;
a_student :- new Student;
a_student.read;
The_school.Place_student(a_student, no_room, ident_exists);
if no_room
then User_message("Sorry, no more room!") else
if ident_exists
then User_message("The identity number is already in use!")
else User_message("The data have been stored.");
end of Enter_student;
procedure Write_student;
begin integer ident_number; ref(Student) a_student;
ident_number := prompt_for_int("Identity number? ");
a_student :- The_school.find_student(ident_number);
if a_student == none
then User_message("No student with that identity number!")
else a_student.write;
end of Write_student;
procedure List_students;
begin ref(Student) a_student;
User_message("The students for which data have been entered:");
a_student :- The_school.first_student;
while a_student =/= none do
begin a_student.write; a_student :- The_school.next_student end;
end of List_students;
procedure Change_student;
begin ref(Student) a_student; integer ident_number;
ident_number := prompt_for_int("Identity number? ");
a_student :- The_school.find_student(ident_number);
if a_student == none
then User_message("No student with that identity number!")
else begin a_student.write; a_student.change end;
end of Change_student;
procedure Remove_student;
begin integer ident_number; Boolean no_such_student;
ident_number := prompt_for_int("Identity number? ");
The_school.Remove_specified_student(ident_number, no_such_student);
if no_such_student
then User_message("No student with that identity number!")
else User_message("The student has been removed!");
end of Remove_student;
procedure Put_to_file;
not_implemented("Put to file");
procedure Get_from_file;
not_implemented("Get from file");
% The procedures which put data to file and get data from file
% will be implemented when more powerful file tools have been
% introduced in chapter 12;
procedure Bad_grades;
begin character grade_limit; ref(Student) a_student;
grade_limit := prompt_for_char("Grade limit? ");
a_student :- The_school.first_student;
while a_student =/= none do
begin
if a_student.worst_grade ge grade_limit then a_student.write;
a_student :- The_school.next_student;
end;
end of Bad_grades;
procedure Sort_form;
begin
integer form, number_in_form, student_number;
ref(Student) array The_form(1 : 300);
ref(Student) a_student;
form := prompt_for_int("Form number? ");
! Make a list of all students in the specified form: ;
a_student :- The_school.first_student;
while a_student =/= none do
begin
if a_student.form = form and then number_in_form < 300 then
begin
number_in_form := number_in_form + 1;
The_form(number_in_form) :- a_student;
end;
a_student :- The_school.next_student;
end;
! Sort the list on age: ;
Sort_on_age(The_form, number_in_form);
! The auxiliary procedure Sort_on_age is declarec below;
! Write the list: ;
for student_number := 1 step 1 until number_in_form do
The_form(student_number).write;
end of Sort_form;
procedure Give_help;
begin
User_message("The legal commands are: ");
User_message(" ?: Help (writes this text)");
User_message(" E: To enter data about a new student");
User_message(" W: Writes data about a specified student");
User_message(" L: Writes a list with all students");
User_message(" C: Changes data about a specified student");
User_message(" R: Removes data about a specified student");
User_message(" P: Puts all data to file ""Stud.dta""");
User_message(" G: Gets data from file ""stud.dta""");
User_message(" B: Writes students with bad grades");
User_message(" S: Writes students in a specified form sorted on age");
User_message(" Q: Quit (the program execution stops)");
end of Give_help;
% ******************************************
% * *
% * Declarations of auxiliary procedures: *
% * *
% ******************************************
procedure Unknown_command(c); character c;
begin
outtext(" You gave the command '"); outchar(c);
outtext("'. This is not among the legal commands."); outimage;
outtext(" Type ? if you don't remember the commands"); outimage;
end of Unknown command;
character procedure prompt_for_char(prompt); text prompt;
begin
outtext(prompt); breakoutimage; inimage;
prompt_for_char := inchar;
end of prompt_for_char;
integer procedure prompt_for_int(prompt); text prompt;
begin
outtext(prompt); breakoutimage; inimage;
prompt_for_int := inint;
end of prompt_for_int;
Boolean procedure prompt_for_bool(prompt); text prompt;
begin character c;
outtext(prompt); breakoutimage; inimage;
c := inchar;
prompt_for_bool := c = 'y' or c = 'Y';
end of prompt_for_char;
procedure not_implemented(action_name); text action_name;
begin
outtext(" You gave the command """); outtext(action_name);
outtext(""". This has not been implemented yet!"); outimage;
outtext(" Try another command!"); outimage;
end;
procedure User_message(message); text message;
begin outtext(message); outimage end;
procedure Sort_on_age(Student_list, list_length);
ref(Student) array Student_list; integer list_length;
begin integer ind, k, index_of_oldest; ref(Student) swap_aux;
for ind := 1 step 1 until list_length - 1 do
begin
index_of_oldest := ind;
for k := ind + 1 step 1 until list_length do
if Student_list(k).is_elder_than(Student_list(index_of_oldest))
then index_of_oldest := k;
if ind ne index_of_oldest then
begin
swap_aux :- Student_list(index_of_oldest);
Student_list(index_of_oldest) :- Student_list(ind);
Student_list(ind) :- swap_aux;
end;
end;
end Sort_on_age;
% ********************************************************
% * *
% * Declaration of a variable to hold the last command *
% * typed by the user: *
% * *
% ********************************************************
character command;
% **********************************************************
% * *
% * Declaration of a variable to hold the data structure *
% * (which is insied a single School-object): *
% * *
% **********************************************************
ref(School) The_school;
% **********************************************************
% * *
% * That was the last declaration. *
% * Now come the imperatives of this program: *
% * *
% **********************************************************
% **********************************************************
% * *
% * Initialization of data structure for 1500 students: *
% * *
% **********************************************************
The_school :- new School(1500);
% ****************************************************
% * *
% * Read and interpret commands typed by the user: *
% * *
% ****************************************************
command := prompt_for_char("Type your first command (? for help) > ");
while command ne 'Q' do
begin
if command = '?' then Give_help else
if command = 'E' then Enter_student else
if command = 'W' then Write_student else
if command = 'L' then List_students else
if command = 'C' then Change_student else
if command = 'R' then Remove_student else
if command = 'P' then Put_to_file else
if command = 'G' then Get_from_file else
if command = 'S' then Sort_form else
if command = 'B' then Bad_grades
else Unknown_command(command);
command := prompt_for_char("Your next command > ");
end;
User_message("Bye");
end